package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustomException;
import com.heima.model.common.dto.PageResponseResult;
import com.heima.model.common.dto.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dto.WmNewsDto;
import com.heima.model.wemedia.dto.WmNewsPageReqDto;
import com.heima.model.wemedia.pojo.WmMaterial;
import com.heima.model.wemedia.pojo.WmNews;
import com.heima.model.wemedia.pojo.WmNewsMaterial;
import com.heima.model.wemedia.pojo.WmUser;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmNewsTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    // @Autowired
    // private WmNewsAutoScanService wmNewsAutoScanService;
    @Autowired
    private WmNewsTaskService wmNewsTaskService;

    /**
     * 查询文章
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {

        // 1.检查参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 分页参数检查
        dto.checkParam();
        // 获取当前登录人的信息
        WmUser user = WmThreadLocalUtil.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        // 2.分页条件查询
        IPage page = new Page(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 状态精确查询
        if (dto.getStatus() != null) {
            lambdaQueryWrapper.eq(WmNews::getStatus, dto.getStatus());
        }

        // 频道精确查询
        if (dto.getChannelId() != null) {
            lambdaQueryWrapper.eq(WmNews::getChannelId, dto.getChannelId());
        }

        // 时间范围查询
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null) {
            lambdaQueryWrapper.between(WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate());
        }

        // 关键字模糊查询
        if (StringUtils.hasLength(dto.getKeyword())) {
            lambdaQueryWrapper.like(WmNews::getTitle, dto.getKeyword());
        }

        // 查询当前登录用户的文章
        lambdaQueryWrapper.eq(WmNews::getUserId, user.getId());

        // 发布时间倒序查询
        lambdaQueryWrapper.orderByDesc(WmNews::getCreatedTime);

        page = page(page, lambdaQueryWrapper);

        // 3.结果返回
        ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        responseResult.setData(page.getRecords());

        return responseResult;
    }

    @Override
    public ResponseResult submitNews(WmNewsDto dto, boolean draft) throws Exception {
        if (WmThreadLocalUtil.getUser() == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 把dto转为news对象
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);

        wmNews.setEnable((short) 1);
        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());

        // 如果没设置发布时间，就设置为立即发布
        if (wmNews.getPublishTime() == null) {
            wmNews.setPublishTime(new Date());
        }

        if (!CollectionUtils.isEmpty(dto.getImages())) {
            // 拼接image集合地址为字符串，用逗号隔开
            wmNews.setImages(String.join(",", dto.getImages()));
        }

        // 草稿和直接发布审核状态不同
        if (draft) {
            wmNews.setStatus(WmNews.Status.NORMAL.getCode());
        } else {
            wmNews.setStatus(WmNews.Status.SUBMIT.getCode());
        }

        // 封面图如果是type = -1 需要自动识别内容中的图片作为封面
        if (dto.getType() == -1) {
            // 对内容中的图片数量进行判断
            // 使用content中的json字符串，转为json对象解析，把type=image的取出来
            List<HashMap> contentList = JSON.parseArray(dto.getContent(), HashMap.class);
            List<String> meterialUrlList = contentList.stream().filter(m -> "image".equals(m.get("type"))).map(m -> (String) m.get("value")).collect(Collectors.toList());
            if (meterialUrlList.size() >= 3) {
                // 三图模式
                wmNews.setType((short) 3);
                String images = meterialUrlList.stream().limit(3).collect(Collectors.joining(","));
                wmNews.setImages(images);
            } else if (meterialUrlList.size() > 0) {
                // 单图模式
                wmNews.setType((short) 1);
                String images = meterialUrlList.stream().limit(1).collect(Collectors.joining(","));
                wmNews.setImages(images);
            } else {
                // 无图模式
                wmNews.setType((short) 0);
            }
        }

        // 根据id判断新增或者修改
        if (dto.getId() != null && dto.getId() > 0) {
            // 修改
            this.updateById(wmNews);
        } else {
            // 新增
            this.save(wmNews);
        }
        // 草稿到此为止，后续操作无需进行

        // 处理中间表
        // 判断是否为草稿，如果是草稿则不进行图文和素材关系关联
        if (!draft) {
            List<WmNewsMaterial> associationList = new ArrayList<>();
            // 内容和中间表的关联
            List<HashMap> contentList = JSON.parseArray(dto.getContent(), HashMap.class);
            List<WmMaterial> meterialList4Content = contentList
                    .stream()
                    .filter(m -> "image".equals(m.get("type")))
                    .map(m -> {
                        // 根据url查询素材表，拿到素材id
                        String url = (String) m.get("value");
                        return wmMaterialMapper.selectOne(Wrappers.<WmMaterial>lambdaQuery().eq(WmMaterial::getUrl, url));
                    })
                    .collect(Collectors.toList());
            for (int i = 0; i < meterialList4Content.size(); i++) {
                WmMaterial wmMaterial = meterialList4Content.get(i);
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                wmNewsMaterial.setMaterialId(wmMaterial.getId());
                wmNewsMaterial.setNewsId(wmNews.getId());
                wmNewsMaterial.setType((short) 0);
                wmNewsMaterial.setOrd((short) i);
                associationList.add(wmNewsMaterial);
            }
            if (StringUtils.hasLength(wmNews.getImages())) {
                // 封面图和中间表的关联
                List<WmMaterial> meterialList4Images = Arrays.stream(wmNews.getImages().split(","))
                        .map(url -> {
                            // 根据url查询素材表，拿到素材id
                            return wmMaterialMapper.selectOne(Wrappers.<WmMaterial>lambdaQuery().eq(WmMaterial::getUrl, url));
                        })
                        .collect(Collectors.toList());
                for (int i = 0; i < meterialList4Images.size(); i++) {
                    WmMaterial wmMaterial = meterialList4Images.get(i);
                    WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                    wmNewsMaterial.setMaterialId(wmMaterial.getId());
                    wmNewsMaterial.setNewsId(wmNews.getId());
                    wmNewsMaterial.setType((short) 1);
                    wmNewsMaterial.setOrd((short) i);
                    associationList.add(wmNewsMaterial);
                }
            }
            if (!associationList.isEmpty()) {
                if (dto.getId() != null && dto.getId() > 0) {
                    // 先删除关联关系，根据图文信息（news）的id删除中间表的关联关系
                    wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery()
                            .eq(WmNewsMaterial::getNewsId, wmNews.getId()));
                }
                // 把中间表关联对象存入数据库中
                associationList.forEach(a -> {
                    wmNewsMaterialMapper.insert(a);
                });
            }
        }
        // 图文信息保存成功后，自动触发审核发布功能
        // wmNewsAutoScanService.autoScanWmNews(wmNews.getId());
        // 调整为根据publishTime延迟审核发布
        wmNewsTaskService.addNewsToTask(wmNews.getId(), wmNews.getPublishTime());
        return ResponseResult.okResult(null);
    }

}
